package com.csj.mvvm.algorithm

import android.util.Base64
import android.util.Log
import java.nio.charset.StandardCharsets
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec

object AESUtil {

    private val TAG = AESUtil::class.java.simpleName

    /**
     * 采用AES加密算法
     */
    private val KEY_ALGORITHM = "AES"

    /**
     * 加解密算法/工作模式/填充方式
     */
    private val CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding"

    /**
     * AES 加密
     *
     * @param secretKey 加密密码，长度：16 或 32 个字符
     * @param data      待加密内容
     * @return 返回Base64转码后的加密数据
     */
    fun encrypt(secretKey: String, data: String, iv: String): String? {
        try {
            // 创建AES秘钥
            val secretKeySpec =
                SecretKeySpec(secretKey.toByteArray(StandardCharsets.UTF_8), KEY_ALGORITHM)
            // 创建密码器
            val cipher = Cipher.getInstance(CIPHER_ALGORITHM)
            // 初始化加密器
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, IvParameterSpec(iv.toByteArray()))
            val encryptByte = cipher.doFinal(data.toByteArray())
            // 将加密以后的数据进行 Base64 编码
            return base64Encode(encryptByte)
        } catch (e: Exception) {
            handleException("encrypt", e)
        }
        return null
    }

    /**
     * 测试加密
     */
    fun encrypt(data: String): String? {
        return encrypt("##thekillboxgame", data, "thekillboxgame##")
    }

    /**
     * AES 解密
     *
     * @param secretKey  解密的密钥，长度：16 或 32 个字符
     * @param content 加密的密文 Base64 字符串
     */
    fun decrypt(secretKey: String, content: String?, iv: String): String? {
        try {
            val raw = secretKey.toByteArray(StandardCharsets.UTF_8)
            val skeySpec = SecretKeySpec(raw, "AES")
            val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
            val ips = IvParameterSpec(iv.toByteArray())
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, ips)
            val encrypted1 = base64Decode(content)
            return try {
                val original = cipher.doFinal(encrypted1)
                String(original)
            } catch (e: Exception) {
                println(e.toString())
                null
            }
        } catch (e: Exception) {
            handleException("decrypt", e)
        }
        return null
    }

    /**
     * 测试解密
     */
    fun decrypt(data: String?): String? {
        return decrypt("##thekillboxgame", data, "thekillboxgame##")
    }


    /**
     * 将 字节数组 转换成 Base64 编码
     * 用Base64.DEFAULT模式会导致加密的text下面多一行（在应用中显示是这样）
     */
    private fun base64Encode(data: ByteArray?): String? {
        return Base64.encodeToString(data, Base64.NO_WRAP)
    }

    /**
     * 将 Base64 字符串 解码成 字节数组
     */
    private fun base64Decode(data: String?): ByteArray {
        return Base64.decode(data, Base64.NO_WRAP)
    }

    /**
     * 处理异常
     */
    private fun handleException(methodName: String, e: Exception) {
        e.printStackTrace()
        Log.e(TAG, "$methodName---->$e")
    }
}